<!DOCTYPE html>
<html>
<header>
    <meta charset="utf-8" />
    <script>

function getFoo () {
  return new Promise(function (resolve, reject){ // 5
    resolve('foo');  // 6
  });
}


const mygenerator = function* () {
  try {
    const foo = yield getFoo(); // 4   //10 foo='foo'
    console.log(foo);    // 11  ->> console.log('foo');
  } catch (e) {
    console.log(e);     
  }
};

function run (mygenerator) {
  const myiterator = mygenerator(); // 2
  let result=myiterator.next();//3  ->> result= { done:false, Promise}

  function go(result) {
    if (result.done) return result.value;

    return result.value.then(function (value) { // 8  ->> result={ done:false, Promise}
      return go(myiterator.next(value));   // 9  ->> go(myiterator.next('foo')) ->>go({done:true,value:undefined})
      //return go(myiterator.throw(error));  
    });
  }
  
  go(result); // 7  ->> result={ done:false, Promise}
}

run(mygenerator);// 1

// 网络图片读取 start
// const preloadImage = function (path) {
//   return new Promise(function (resolve, reject) {
//     const image = new Image();
//     image.onload  = resolve;
//     image.onerror = reject;
//     image.src = path;
//   });
// };

// let url1="http://pic1.hualongxiang.com/attachment/Day_220622/103_3331922_c1245a43ded3.png?x-oss-process=image/resize,w_780";
// let p1= preloadImage(url1)
// .then(function(){
//   return Promise.resolve("OK1");
// }).catch(function(){
//   return Promise.reject("ERR1");
// });

// let url2="http://pic1.hualongxiang.com/attachment/Day_220622/103_3331922_c1245a43ded3.png?x-oss-process=image/resize,w_780";
// let p2= preloadImage(url2)
// .then(function(){
//   return   Promise.resolve("OK2");
// }).catch(function(){
//   return Promise.reject("ERR2"); 
// });

// let url3="http://pic1.hualongxiang.com/attachment/Day_220622/103_3331922_c1245a43ded3.png?x-oss-process=image/resize,w_780";
// let p3= preloadImage(url3)
// .then(function(){
//   return Promise.resolve("OK3");
// }).catch(function(){
//   return Promise.reject("ERR3");
// });

// // （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。
// // （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。
// const allPromise = Promise.all([p1, p2, p3]);
// allPromise.then(function (results) {
//   console.log(results);
// }).catch(function(reason){
//   console.log(reason);
// });

// // 只要p1、p2、p3之中有一个实例率先改变状态，p的状态就跟着改变。那个率先改变的 Promise 实例的返回值，就传递给p的回调函数。
// const tracePromise = Promise.race([p1, p2, p3]);
// tracePromise.then(function (results) {
//   console.log(results);
// }).catch(function(reason){
//   console.log(reason);
// });

// // 有时候，我们希望等到一组异步操作都结束了，不管每一个操作是成功还是失败，再进行下一步操作。
// // 但是，现有的 Promise 方法很难实现这个要求。
// const allSettledPromise = Promise.allSettled([p1,p2,p3]);
// allSettledPromise.then(function (results) {
//   console.log(results);
// });

// // 只要参数实例有一个变成fulfilled状态，
// // 包装实例就会变成fulfilled状态；如果所有参数实例都变成rejected状态，包装实例就会变成rejected状态。
// const anyPromise = Promise.any([p1,p2,p3]);
// anyPromise.then(function (results) {
//   console.log(results);
// }).catch(function(err){
//   console.log(err);
// });
// // 网络图片读取 end 

// // 下面代码中，setTimeout(fn, 0)
// // 在下一轮“事件循环”开始时执行，
// // Promise.resolve()在本轮“事件循环”结束时执行，console.log('one')
// // 则是立即执行，因此最先输出。
// setTimeout(function () {
//   console.log('three');
// }, 0);

// Promise.resolve().then(function () {
//   console.log('two');
// });

// console.log('one');

// const p = Promise.resolve('Hello');

// p.then(function (s) {
//   console.log(s)
// });
// // Hello

// let thenable = {
//   then: function(resolve, reject) {
//     resolve(42);
//   }
// };

// let p1 = Promise.resolve(thenable);
// p1.then(function (value) {
//   console.log(value);  // 42
// });

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。
// （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。
// Promise.all()  

// 只要p1、p2、p3之中有一个实例率先改变状态，p的状态就跟着改变。那个率先改变的 Promise 实例的返回值，就传递给p的回调函数。
// Promise.race()

// 有时候，我们希望等到一组异步操作都结束了，不管每一个操作是成功还是失败，再进行下一步操作。
// 但是，现有的 Promise 方法很难实现这个要求。
// Promise.allSettled()

// 只要参数实例有一个变成fulfilled状态，
// 包装实例就会变成fulfilled状态；如果所有参数实例都变成rejected状态，包装实例就会变成rejected状态。
// Promise.any()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// var resolved = Promise.resolve(42);
// var rejected = Promise.reject(-1);
// var alsoRejected = Promise.reject(Infinity);

// Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
//   console.log(result); // 42
// });

// Promise.any([rejected, alsoRejected]).catch(function (results) {
//   console.log(results instanceof AggregateError); // true
//   console.log(results.errors); // [-1, Infinity]
// });

// const resolved = Promise.resolve(42);
// const rejected = Promise.reject(-1);

// const allSettledPromise = Promise.allSettled([resolved, rejected]);

// allSettledPromise.then(function (results) {
//   console.log(results);
// });


// const p1 = new Promise((resolve, reject) => {
//   setTimeout( () => resolve('hello'),6000);  
// })

// const p = Promise.race([
//   p1,
//   new Promise(function (resolve, reject) {
//     setTimeout(() => reject(new Error('request timeout')), 5000)
//   })
// ]);

// p.then(console.log)
// .catch(console.error);

// const p1 = new Promise((resolve, reject) => {
//   resolve('hello');
// })
// .then(result => result)
// .catch(e => e);

// const p2 = new Promise((resolve, reject) => {
//   throw new Error('报错了');
// })
// .then(result => result)
// .catch(e => e);

// Promise.all([p1, p2])
// .then(
//   result => console.log(result)
//   )
// .catch(
//   e => console.log(e)
//   );


// ["hello", Error: 报错了]

// const someAsyncThing = function() {
//   return new Promise(function(resolve, reject) {
//     // 下面一行会报错，因为x没有声明
//     reject(x + 2);
//   });
// };
// someAsyncThing().then(function() {
  
// }).catch(function(error) {
//   console.log('oh no', error);
//   // 下面一行会报错，因为y没有声明
//   y + 2;
// }).catch(function(error) {
//   console.log('carry on', error);
// });
// oh no [ReferenceError: x is not defined]
// carry on [ReferenceError: y is not defined]



// Promise.resolve()
// .catch(function(error) {
//   console.log('oh no', error);
// })
// .then(function() {
//   console.log('carry on');
// });
// // carry on

// const someAsyncThing = function() {
//   return new Promise(function(resolve, reject) {
//     // 下面一行会报错，因为x没有声明
//     let x=1;
//     reject(x + 2);
//   });
// };

// someAsyncThing().then(function() {
//   console.log('carry on');
// })
// .catch(function(error) {
//   console.log('oh no', error);
//   // return new Promise(function(resolve, reject) {
//   //  resolve(55);
//   // });
// });

// oh no [ReferenceError: x is not defined]
// carry on

// const p1 = new Promise(function (resolve, reject) {
//   setTimeout(() => reject(new Error('fail')), 3000)
// })

// const p2 = new Promise(function (resolve, reject) {
//   setTimeout(() => resolve(p1), 1000)
// })

// p2
//   .then(result => console.log(result))
//   .catch(error => console.log(error))

// const getJSON = function(url) {
//   const promise = new Promise(function(resolve, reject){
//     const handler = function() {
//       if (this.readyState !== 4) {
//         return;
//       }
//       if (this.status === 200) {
//         resolve(this.response);
//       } else {
//         reject(new Error(this.statusText));
//       }
//     };
//     const client = new XMLHttpRequest();
//     client.open("GET", url);
//     client.onreadystatechange = handler;
//     client.responseType = "json";
//     client.setRequestHeader("Accept", "application/json");
//     client.send();

//   });

//   return promise;
// };

// getJSON("./json/myjson.json").then(function(json) {
//   console.log('Contents: ' + json);
// }, function(error) {
//   console.error('出错了', error);
// });


        // function loadImageAsync(url) {
        //     return new Promise(function (resolve, reject) {
        //         const image = new Image();

        //         image.onload = function () {
        //             alert("onload");
        //             resolve(image);
        //         };

        //         image.onerror = function () {
        //             alert("onerror");
        //             reject(new Error('Could not load image at ' + url));
        //         };

        //         image.src = url;
        //     });
        // }
        // let myimgpromise = loadImageAsync("http://pic1.hualongxiang.com/attachment/Day_220622/103_3331922_c1245a43ded3.png?x-oss-process=image/resize,w_780")
        
        // myimgpromise.then(function(image){
        //     alert(image);
        //     document.body.append(image);
        // })
        
        // let mypromise = new Promise(function (resolve, reject) {
        //     // resolve(0);
        //     reject(-1);
        // });
        // mypromise.then(function (value) {
        //     alert(value);
        // }).catch(function (err) {
        //     alert(err);
        // });
        // alert(11);


        // function timeout(ms) {
        //     return new Promise((resolve, reject) => {
        //         setTimeout(resolve, ms, 'done');
        //     });
        // }

        // timeout(100).then((value) => {
        //     console.log(value);
        // });
    </script>
</header>

<body>
    <img src="" id="myimg" />
</body>

</html>